﻿/**
 * 
 * Copyright 2009, 2010 Mike Jamer [email: mikejamer@gmail.com ]
 * 
 * This File is part of Moose IRC
 * 
 * MooseIRC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * MooseIRC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with MooseIRC.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using moose.irc;

namespace TestChannelStructure {

    /// <summary>
    /// Form Used to test the Channel Infastructure
    /// </summary>
    public partial class ChannelDebugForm
        : Form {

        #region [Local Attributes]

        /// <summary>
        /// Collection of channels
        /// </summary>
        private Dictionary<string, IrcChannel> m_channels;

        #endregion

        #region [Construction]

        /// <summary>
        /// Initialize Channel Testing Form
        /// </summary>
        public ChannelDebugForm() {
            InitializeComponent();
            m_channels = new Dictionary<string, IrcChannel>();
            return;
        }

        #endregion

        #region [Helper Methods]

        /// <summary>
        /// Create a new channel
        /// </summary>
        /// <param name="channel_name">Name of new channe;</param>
        private void create_channel(string channel_name) {
            if (!m_channels.ContainsKey(channel_name))
                m_channels[channel_name] = new IrcChannel(channel_name);
            return;
        }

        /// <summary>
        /// Remove an existing channel
        /// </summary>
        /// <param name="channel_name">name of channel to remove</param>
        private void remove_channel(string channel_name) {
            if (m_channels.ContainsKey(channel_name))
                m_channels.Remove(channel_name);
            return;
        }

        /// <summary>
        /// Add a user to a channel
        /// </summary>
        /// <param name="channel_name">name of channel</param>
        /// <param name="user_string">user string for user</param>
        private void add_user(string channel_name, string user_string) {
            if (!m_channels.ContainsKey(channel_name)) return;
            IrcChannel channel = m_channels[channel_name];
            channel.add_user(new IrcUser(user_string));
            //channel.add_user(user_string);
            return;
        }

        /// <summary>
        /// Remove user from a channel
        /// </summary>
        /// <param name="channel_name">name of channel</param>
        /// <param name="user_string">user string for user</param>
        private void remove_user(string channel_name, string user_string) {
            if (!m_channels.ContainsKey(channel_name)) return;
            IrcChannel channel = m_channels[channel_name];
            //channel.remove_user(user_string);
            channel.remove_user(new IrcUser(user_string));
            return;
        }

        /// <summary>
        /// Update the channel modes
        /// </summary>
        /// <param name="channel_name">name of the channel</param>
        /// <param name="mode_string">mode string, used to modify channel modes</param>
        public void update_modes(string channel_name, string mode_string) {
            if (!m_channels.ContainsKey(channel_name)) return;
            IrcChannel channel = m_channels[channel_name];
            channel.update_modes(mode_string);
            return;
        }

        /// <summary>
        /// Fill Channels List Box with all the channels
        /// </summary>
        private void fill_channels() {
            lstChannels.Items.Clear();
            lstChannels.DisplayMember = "Name";
            foreach (IrcChannel channel in m_channels.Values)
                lstChannels.Items.Add(channel);
            return;
        }

        /// <summary>
        /// Fill Users List View for specified channel
        /// </summary>
        /// <param name="channel_name">name of channel to fill users for</param>
        private void fill_users(string channel_name) {
            if (!m_channels.ContainsKey(channel_name)) return;
            lstUsers.Items.Clear();
            lstUsers.DisplayMember = "Name";
            foreach (IrcUser user in m_channels[channel_name].get_users())
                lstUsers.Items.Add(user);
            return;
        }

        /// <summary>
        /// Fill Channel Modes
        /// </summary>
        /// <param name="channel_name">name of channel to fill modes for</param>
        private void fill_modes(string channel_name) {
            if (!m_channels.ContainsKey(channel_name)) return;
            lstModes.Items.Clear();
            lstModes.DisplayMember = "Mode";
            foreach (IrcChannelMode mode in m_channels[channel_name].get_modes())
                lstModes.Items.Add(mode);
            return;
        }

        /// <summary>
        /// Fill Channel Mode Parameters
        /// </summary>
        /// <param name="channel_name">name of channel to fill parameters in for</param>
        /// <param name="mode">mode to fill parameters for</param>
        private void fill_mode_parameters(string channel_name, char mode) {
            if (!m_channels.ContainsKey(channel_name)) return;
            var modes = from IrcChannelMode m in m_channels[channel_name].get_modes()
                        where m.Mode == mode
                        select m;

            if (modes.Count() == 0) return;

            lstModeParameters.Items.Clear();
            foreach (string parameter in modes.First().get_arguments()) 
                lstModeParameters.Items.Add(parameter);
            return;
        }

        #endregion

        #region [Form Events]

        /// <summary>
        /// Fires when user clicks add channel
        /// </summary>
        private void cmdAddChannel_Click(object sender, EventArgs e) {
            create_channel(txtChannelName.Text);
            fill_channels();
            fill_users(txtChannelName.Text);
            fill_modes(txtChannelName.Text);
            return;
        }

        /// <summary>
        /// Fires whne user clicks add user
        /// </summary>
        private void cmdAddUser_Click(object sender, EventArgs e) {
            add_user(txtChannelName.Text, txtUserName.Text);
            fill_users(txtChannelName.Text);
            fill_modes(txtChannelName.Text);
            return;
        }

        /// <summary>
        /// Fires when user clicks remove user
        /// </summary>
        private void cmdRemoveUser_Click(object sender, EventArgs e) {
            remove_user(txtChannelName.Text, txtUserName.Text);
            fill_users(txtChannelName.Text);
            fill_modes(txtChannelName.Text);
            return;
        }

        /// <summary>
        /// Fires when user clicks update mode button
        /// </summary>
        private void cmdUpdateMode_Click(object sender, EventArgs e) {
            update_modes(txtChannelName.Text, txtModeString.Text);
            fill_modes(txtChannelName.Text);
            return;
        }

        /// <summary>
        /// Fires when user selects a new index in the channel list
        /// </summary>
        private void lstChannels_SelectedIndexChanged(object sender, EventArgs e) {
            if (lstChannels.SelectedItem != null) {
                txtChannelName.Text = ((IrcChannel)lstChannels.SelectedItem).Name;
                fill_users(txtChannelName.Text);
                fill_modes(txtChannelName.Text);
            }
            return;
        }

        /// <summary>
        /// Fires when user selects a user from a channel
        /// </summary>
        private void lstUsers_SelectedIndexChanged(object sender, EventArgs e) {
            if (lstUsers.SelectedItem != null)
                txtUserName.Text = ((IrcUser)lstUsers.SelectedItem).Name;
            return;
        }

        /// <summary>
        /// Fires when user selects a channel mode
        /// </summary>
        private void lstModes_SelectedIndexChanged(object sender, EventArgs e) {
            if (lstModes.SelectedItem != null)
                fill_mode_parameters(txtChannelName.Text,((IrcChannelMode)lstModes.SelectedItem).Mode);
            return;
        }

        #endregion

        
    }
}
